{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Country Names Map\n",
    "\n",
    "This loads a GeoJSON with all country borders which are then shown on a map according to their names starting with a certain letter to be chosen with a slider in the corner of the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from functools import partial\n",
    "from string import ascii_uppercase\n",
    "\n",
    "from ipywidgets import IntSlider, Layout\n",
    "from ipyleaflet import basemaps, Map, GeoJSON, LayersControl, FullScreenControl, WidgetControl\n",
    "\n",
    "from xyzspaces.datasets import get_countries_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_countries(a_map, features):\n",
    "    \"Add a list of GeoJSON objects to a map.\"\n",
    "    other_layers = [l for l in a_map.layers if type(l) != GeoJSON]\n",
    "    a_map.layers = tuple(other_layers)\n",
    "    for f in features:\n",
    "        gj_layer = GeoJSON(data=f, name=f[\"properties\"][\"name\"])\n",
    "        a_map.add_layer(gj_layer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def slider_moved(event, the_map=None, the_features=None):\n",
    "    \"Callback for slider events.\"\n",
    "    if event.type != 'change' or type(event.new) != int:\n",
    "        return\n",
    "    n = event.new\n",
    "    assert 0 <= n < 26\n",
    "    ch = ascii_uppercase[n]\n",
    "    features = [f for f in the_features[\"features\"] \n",
    "        if f[\"properties\"][\"name\"].upper().startswith(ch)\n",
    "        # if ch in f[\"properties\"][\"name\"].upper()\n",
    "    ]\n",
    "    event[\"owner\"].description = f\"{len(features)} x {ch}\"\n",
    "    add_countries(the_map, features)    \n",
    "    names = [f[\"properties\"][\"name\"] for f in features]\n",
    "    return names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "countries = get_countries_data()\n",
    "\n",
    "m = Map(zoom=2, basemap=basemaps.OpenStreetMap[\"Mapnik\"])\n",
    "m += FullScreenControl(position=\"topleft\")\n",
    "m += LayersControl(position=\"topright\")\n",
    "\n",
    "layout = Layout(width=\"500px\")\n",
    "letter_slider = IntSlider(min=0, max=25, step=1, value=1, description=\" \", layout=layout)\n",
    "letter_slider.observe(partial(slider_moved, the_map=m, the_features=countries))\n",
    "widget_control1 = WidgetControl(widget=letter_slider, position='bottomleft', layout=layout)\n",
    "m += widget_control1\n",
    "\n",
    "# This is needed to trigger the first slider change event,\n",
    "# or the map would be empty at the start:\n",
    "letter_slider.value = 0\n",
    "\n",
    "m"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
